<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>智能化测试用例生成</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            color: #333;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        .header {
            text-align: center;
            margin-bottom: 30px;
            color: white;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }

        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }

        .main-content {
            background: white;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            overflow: hidden;
        }

        .nav-tabs {
            display: flex;
            background: #f8f9fa;
            border-bottom: 1px solid #e1e5e9;
        }

        .nav-tab {
            flex: 1;
            padding: 15px 20px;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s ease;
            border: none;
            background: none;
            font-size: 16px;
            font-weight: 500;
            color: #666;
        }

        .nav-tab:hover {
            background: #e9ecef;
            color: #333;
        }

        .nav-tab.active {
            background: white;
            color: #667eea;
            border-bottom: 3px solid #667eea;
        }

        .content {
            padding: 30px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }

        .form-control {
            width: 100%;
            padding: 12px;
            border: 2px solid #e1e5e9;
            border-radius: 6px;
            font-size: 14px;
            transition: border-color 0.3s ease;
        }

        .form-control:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }

        textarea.form-control {
            resize: vertical;
            min-height: 120px;
        }

        .file-upload {
            border: 2px dashed #ddd;
            border-radius: 6px;
            padding: 30px;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
        }

        .file-upload:hover {
            border-color: #667eea;
            background: #f8f9fa;
        }

        .file-upload.dragover {
            border-color: #667eea;
            background: #e3f2fd;
        }

        .file-upload input[type="file"] {
            position: absolute;
            opacity: 0;
            width: 100%;
            height: 100%;
            cursor: pointer;
        }

        .file-upload-text {
            font-size: 16px;
            color: #667eea;
            margin-bottom: 8px;
        }

        .file-upload-hint {
            font-size: 12px;
            color: #666;
        }

        .test-types {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 12px;
        }

        .test-type-item {
            position: relative;
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            border-radius: 6px;
            overflow: hidden;
        }

        .test-type-item input[type="checkbox"] {
            position: absolute;
            opacity: 0;
            width: 0;
            height: 0;
        }

        .test-type-item label {
            display: inline-block;
            padding: 8px 16px;
            background: #f8f9fa;
            border: 2px solid #e9ecef;
            border-radius: 6px;
            color: #495057;
            font-weight: 500;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            position: relative;
            white-space: nowrap;
            user-select: none;
            min-width: 60px;
            text-align: center;
        }

        .test-type-item:hover label {
            transform: translateY(-1px);
            border-color: #667eea;
            color: #667eea;
            background: #f0f2ff;
        }

        .test-type-item input[type="checkbox"]:checked + label {
            background: #667eea;
            border-color: #667eea;
            color: white;
            transform: translateY(-1px);
        }

        .test-type-item.selected {
            animation: pulse 0.3s ease-in-out;
        }

        @keyframes pulse {
            0% {
                transform: scale(1);
            }
            50% {
                transform: scale(1.02);
            }
            100% {
                transform: scale(1);
            }
        }

        .btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 6px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            width: 100%;
            margin-top: 15px;
        }

        .btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3);
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        .loading {
            display: none;
            text-align: center;
            padding: 15px;
        }

        .loading.show {
            display: block;
        }

        .progress-bar {
            width: 100%;
            height: 4px;
            background: #e1e5e9;
            border-radius: 2px;
            overflow: hidden;
            margin: 15px 0;
        }

        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #667eea, #764ba2);
            width: 0%;
            transition: width 0.3s ease;
            animation: progress 2s ease-in-out infinite;
        }

        @keyframes progress {
            0% { width: 0%; }
            50% { width: 70%; }
            100% { width: 100%; }
        }

        .loading-text {
            color: #667eea;
            font-weight: 600;
            margin-top: 8px;
            font-size: 14px;
        }

        .alert {
            padding: 12px;
            border-radius: 4px;
            margin: 15px 0;
            display: none;
        }

        .alert.success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }

        .alert.error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }

        .alert.info {
            background: #e3f2fd;
            color: #1976d2;
            border: 1px solid #42a5f5;
        }

        .alert.warning {
            background: #fff3e0;
            color: #f57c00;
            border: 1px solid #ffb74d;
        }

        .alert.show {
            display: block;
        }

        .uploaded-file {
            background: #e3f2fd;
            border: 1px solid #2196f3;
            border-radius: 4px;
            padding: 12px;
            margin-top: 8px;
            display: none;
        }

        .uploaded-file.show {
            display: block;
        }

        .file-info {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .file-details {
            flex: 1;
        }

        .file-name {
            font-weight: 600;
            color: #2196f3;
            margin-bottom: 4px;
        }

        .file-path {
            font-size: 12px;
            color: #666;
            margin-bottom: 2px;
        }

        .file-status {
            font-size: 12px;
            color: #4caf50;
            font-style: italic;
        }

        .remove-file {
            background: #f44336;
            color: white;
            border: none;
            padding: 4px 8px;
            border-radius: 3px;
            cursor: pointer;
            font-size: 11px;
        }

        /* 用例列表表格样式 */
        .cases-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
            background: white;
            border: 1px solid #e1e5e9;
            border-radius: 4px;
            overflow: hidden;
        }

        .cases-table th {
            background: #f8f9fa;
            padding: 12px 8px;
            text-align: left;
            font-weight: 600;
            color: #333;
            border-bottom: 1px solid #e1e5e9;
            font-size: 14px;
        }

        .cases-table td {
            padding: 12px 8px;
            border-bottom: 1px solid #f1f3f4;
            font-size: 14px;
            vertical-align: middle;
        }

        .cases-table tr:hover {
            background: #f8f9fa;
        }

        .cases-table tr:last-child td {
            border-bottom: none;
        }

        .case-checkbox {
            width: 16px;
            height: 16px;
            cursor: pointer;
        }

        .case-id {
            background: #667eea;
            color: white;
            padding: 4px 8px;
            border-radius: 12px;
            font-size: 12px;
            font-weight: 600;
            display: inline-block;
        }

        .case-priority {
            padding: 2px 6px;
            border-radius: 10px;
            font-size: 12px;
            font-weight: 600;
            color: white;
        }

        .priority-p1 { background: #dc3545; }
        .priority-p2 { background: #fd7e14; }
        .priority-p3 { background: #ffc107; color: #212529; }
        .priority-p4 { background: #6c757d; }

        .case-title {
            font-weight: 600;
            color: #333;
            max-width: 200px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .case-category {
            color: #666;
            font-size: 13px;
        }

        .case-actions {
            display: flex;
            gap: 6px;
        }

        .btn-small {
            padding: 4px 8px;
            border: none;
            border-radius: 3px;
            font-size: 12px;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
            z-index: 1;
            pointer-events: auto;
        }

        .btn-view {
            background: #667eea;
            color: white;
        }

        .btn-view:hover {
            background: #5a6fd8;
        }

        .btn-delete {
            background: #dc3545;
            color: white;
        }

        .btn-delete:hover {
            background: #c82333;
        }

        .btn-export {
            background: #28a745;
            color: white;
        }

        .btn-export:hover {
            background: #218838;
        }

        /* 分页容器样式 */
        .pagination-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 20px;
            padding: 15px 0;
            border-top: 1px solid #e1e5e9;
        }

        .page-size-selector {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .page-size-selector label {
            font-size: 14px;
            color: #666;
            margin: 0;
        }

        .page-size-selector select {
            padding: 6px 12px;
            border: 1px solid #e1e5e9;
            border-radius: 4px;
            font-size: 14px;
            background: white;
            cursor: pointer;
        }

        .pagination {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .pagination button {
            padding: 8px 12px;
            border: 1px solid #e1e5e9;
            background: white;
            color: #333;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.3s ease;
        }

        .pagination button:hover:not(:disabled) {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }

        .pagination button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .pagination button.active {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }

        .pagination-info {
            color: #666;
            font-size: 14px;
            margin: 0 15px;
        }

        /* 确保按钮可点击 */
        .case-actions {
            display: flex;
            gap: 5px;
            justify-content: center;
        }

        .case-actions button {
            min-width: 40px;
            white-space: nowrap;
        }

        /* 分页样式 */
        .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-top: 20px;
            gap: 8px;
        }

        .pagination button {
            padding: 8px 12px;
            border: 1px solid #ddd;
            background: white;
            color: #333;
            cursor: pointer;
            border-radius: 4px;
            font-size: 14px;
        }

        .pagination button:hover {
            background: #f8f9fa;
        }

        .pagination button.active {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }

        .pagination button:disabled {
            background: #f8f9fa;
            color: #ccc;
            cursor: not-allowed;
        }

        /* 模态框样式 */
        .modal {
            display: none;
            position: fixed;
            z-index: 1000;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.5);
        }

        .modal-content {
            background-color: white;
            margin: 5% auto;
            padding: 20px;
            border-radius: 8px;
            width: 80%;
            max-width: 800px;
            max-height: 80vh;
            overflow-y: auto;
        }

        .modal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #e1e5e9;
        }

        .modal-title {
            font-size: 18px;
            font-weight: 600;
            color: #333;
        }

        .close {
            color: #aaa;
            font-size: 28px;
            font-weight: bold;
            cursor: pointer;
            padding: 8px 12px;
            border-radius: 4px;
            transition: all 0.2s ease;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-width: 40px;
            min-height: 40px;
            background: transparent;
            border: none;
        }

        .close:hover {
            color: #fff;
            background: #ff4757;
            transform: scale(1.1);
        }

        .close:active {
            transform: scale(0.95);
        }

        .case-detail {
            line-height: 1.6;
        }

        .case-detail h3 {
            color: #333;
            margin-bottom: 10px;
        }

        .case-detail .detail-item {
            margin-bottom: 15px;
        }

        .case-detail .detail-label {
            font-weight: 600;
            color: #555;
            margin-bottom: 5px;
        }

        .case-detail .detail-value {
            color: #333;
            padding: 8px;
            background: #f8f9fa;
            border-radius: 4px;
            border-left: 3px solid #667eea;
        }

        .case-detail .steps-list {
            margin-top: 10px;
        }

        .case-detail .step-item {
            margin-bottom: 10px;
            padding: 10px;
            background: #f8f9fa;
            border-radius: 4px;
            border-left: 3px solid #667eea;
        }

        .case-detail .step-number {
            font-weight: 600;
            color: #667eea;
        }

        .case-detail .step-description {
            margin: 5px 0;
        }

        .case-detail .step-expected {
            color: #28a745;
            font-style: italic;
        }

        @media (max-width: 768px) {
            .container {
                padding: 10px;
            }
            
            .header h1 {
                font-size: 2em;
            }
            
            .content {
                padding: 20px;
            }
            
            .nav-tabs {
                flex-direction: column;
            }
            
            .test-types {
                flex-wrap: wrap;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>智能化用例生成</h1>
            <p>基于AI的智能测试用例生成工具</p>
        </div>
        
        <div class="main-content">
            <div class="nav-tabs">
                <button class="nav-tab active" onclick="showTab('generate')">生成用例</button>
                <button class="nav-tab" onclick="showTab('list')">查看用例</button>
            </div>
            
            <div class="content">
                <!-- 生成用例页面 -->
                <div id="generateTab">
                    <form id="testCaseForm">
                        <div class="form-group">
                            <label for="projectName">项目名称</label>
                            <input type="text" id="projectName" name="projectName" placeholder="请输入项目名称" class="form-control">
                        </div>
                        
                        <div class="form-group">
                            <label for="moduleName">模块名称</label>
                            <input type="text" id="moduleName" name="moduleName" placeholder="请输入模块名称" class="form-control">
                        </div>
                        
                        <div class="form-group">
                            <label for="requirement">需求描述</label>
                            <textarea id="requirement" name="requirement" placeholder="请详细描述测试需求，包括功能点、业务流程等" class="form-control"></textarea>
                        </div>
                        
                        <div class="form-group">
                            <label>上传需求文档（可选）</label>
                            <div class="file-upload" id="fileUpload">
                                <input type="file" id="requirementFile" accept=".txt,.doc,.docx,.pdf">
                                <div class="file-upload-text">点击或拖拽文件到此处</div>
                                <div class="file-upload-hint">支持 .txt, .doc, .docx, .pdf 格式，最大50MB，完整保留文档内容</div>
                            </div>
                            <div class="uploaded-file" id="uploadedFile">
                                <div class="file-info">
                                    <div class="file-details">
                                        <div class="file-name" id="fileName"></div>
                                        <div class="file-path" id="filePath"></div>
                                        <div class="file-status" id="fileStatus">准备解析...</div>
                                    </div>
                                    <button type="button" class="remove-file" onclick="removeFile()">删除</button>
                                </div>
                            </div>
                        </div>
                        
                        <div class="form-group">
                            <label>测试类型：</label>
                            <div class="test-types">
                                <div class="test-type-item" onclick="toggleTestType(this)">
                                    <input type="checkbox" id="functional" value="功能" checked>
                                    <label for="functional">功能</label>
                                </div>
                                <div class="test-type-item" onclick="toggleTestType(this)">
                                    <input type="checkbox" id="api" value="接口">
                                    <label for="api">接口</label>
                                </div>
                                <div class="test-type-item" onclick="toggleTestType(this)">
                                    <input type="checkbox" id="performance" value="性能">
                                    <label for="performance">性能</label>
                                </div>
                                <div class="test-type-item" onclick="toggleTestType(this)">
                                    <input type="checkbox" id="ui" value="UI">
                                    <label for="ui">UI</label>
                                </div>
                                <div class="test-type-item" onclick="toggleTestType(this)">
                                    <input type="checkbox" id="business" value="业务">
                                    <label for="business">业务</label>
                                </div>
                                <div class="test-type-item" onclick="toggleTestType(this)">
                                    <input type="checkbox" id="security" value="安全">
                                    <label for="security">安全</label>
                                </div>
                            </div>
                        </div>
                        
                        <div class="form-actions" style="display: flex; gap: 12px; margin-top: 20px;">
                            <button type="submit" class="btn" id="generateBtn">生成测试用例</button>
                        </div>
                    </form>
                    
                    <div class="loading" id="loading">
                        <div class="progress-bar">
                            <div class="progress-fill"></div>
                        </div>
                        <div class="loading-text">正在生成测试用例，请稍候...</div>
                        <div class="loading-details" id="loadingDetails" style="margin-top: 10px; font-size: 12px; color: #666; display: none;">
                            <div id="progressText">正在分析需求复杂度...</div>
                            <div id="timeoutInfo" style="margin-top: 5px; color: #888;"></div>
                            <div class="batch-progress" id="batchProgress" style="display: none; margin-top: 10px;">
                                <div class="batch-info" style="margin-bottom: 5px; font-weight: bold;">
                                    批次进度: <span id="batchCurrent">1</span> / <span id="batchTotal">1</span>
                                </div>
                                <div class="batch-progress-bar" style="width: 100%; height: 8px; background: #f0f0f0; border-radius: 4px; overflow: hidden;">
                                    <div class="batch-progress-fill" id="batchProgressFill" style="height: 100%; background: #4caf50; width: 0%; transition: width 0.3s ease;"></div>
                                </div>
                                <div class="batch-details" id="batchDetails" style="margin-top: 5px; color: #666;">准备开始生成...</div>
                            </div>
                        </div>
                    </div>
                    
                    <div class="alert" id="alert"></div>
                </div>
                
                <!-- 查看用例页面 -->
                <div id="listTab" style="display: none;">
                    <div class="batch-actions" style="margin-bottom: 20px; display: flex; gap: 12px; justify-content: flex-start;">
                        <button class="btn btn-small btn-export" onclick="exportSelectedCases()" style="flex: 1; max-width: 120px;">导出</button>
                        <button class="btn btn-small" onclick="selectAllCases()" style="flex: 1; max-width: 120px;">全选</button>
                        <button class="btn btn-small" onclick="deselectAllCases()" style="flex: 1; max-width: 120px;">取消全选</button>
                        <button class="btn btn-small btn-delete" onclick="deleteSelectedCases()" style="flex: 1; max-width: 120px;">删除选中</button>
                        <button class="btn btn-small" onclick="testViewFunction()" style="flex: 1; max-width: 120px; background-color: #17a2b8;">测试查看</button>
                    </div>

                    <!-- 用例表格 -->
                    <table class="cases-table" id="casesTable">
                        <thead>
                            <tr>
                                <th width="40"><input type="checkbox" id="selectAll" onchange="toggleSelectAll()"></th>
                                <th width="100">用例ID</th>
                                <th width="60">优先级</th>
                                <th>用例标题</th>
                                <th width="100">测试类型</th>
                                <th width="120">操作</th>
                            </tr>
                        </thead>
                        <tbody id="casesTableBody">
                            <!-- 用例数据将在这里动态生成 -->
                        </tbody>
                    </table>

                    <!-- 分页控件 -->
                    <div class="pagination-container">
                        <!-- 每页数量选择器 -->
                        <div class="page-size-selector">
                            <label for="pageSizeSelect">每页显示：</label>
                            <select id="pageSizeSelect" onchange="changePageSize(this.value)">
                                <option value="20" selected>20条</option>
                                <option value="30">30条</option>
                                <option value="50">50条</option>
                                <option value="100">100条</option>
                                <option value="200">200条</option>
                            </select>
                        </div>

                        <!-- 分页控件 -->
                        <div class="pagination" id="pagination">
                            <!-- 分页按钮将在这里动态生成 -->
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 用例详情模态框 -->
    <div id="caseDetailModal" class="modal">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title">用例详情</h3>
                <span class="close" onclick="closeCaseDetail()">&times;</span>
            </div>
            <div class="case-detail" id="caseDetailContent">
                <!-- 用例详情内容将在这里动态生成 -->
            </div>
        </div>
    </div>

    <script>
        const form = document.getElementById('testCaseForm');
        const loading = document.getElementById('loading');
        const alert = document.getElementById('alert');
        const generateBtn = document.getElementById('generateBtn');
        const fileUpload = document.getElementById('fileUpload');
        const requirementFile = document.getElementById('requirementFile');
        const uploadedFile = document.getElementById('uploadedFile');
        const fileName = document.getElementById('fileName');
        const filePath = document.getElementById('filePath');
        const fileStatus = document.getElementById('fileStatus');

        // 全局变量
        let currentPage = 1;
        let pageSize = 20; // 默认20条数据
        let allTestCases = [];
        let totalTestCases = 0;
        let selectedCases = new Set();

        // 测试类型映射
        const testTypeMap = {
            'functional': '功能测试',
            'performance': '性能测试',
            'security': '安全测试',
            'compatibility': '兼容性测试',
            'usability': '易用性测试',
            'interface': '接口测试',
            'unit': '单元测试',
            'integration': '集成测试',
            'system': '系统测试',
            'acceptance': '验收测试'
        };

        // 获取测试类型的中文名称
        function getTestTypeName(testType) {
            return testTypeMap[testType] || testType || '功能测试';
        }

        // 标签页切换
        function showTab(tabName) {
            // 更新标签页状态
            document.querySelectorAll('.nav-tab').forEach(tab => tab.classList.remove('active'));

            // 找到对应的标签页按钮并激活
            const tabs = document.querySelectorAll('.nav-tab');
            tabs.forEach(tab => {
                if ((tabName === 'generate' && tab.textContent.includes('生成用例')) ||
                    (tabName === 'list' && tab.textContent.includes('查看用例'))) {
                    tab.classList.add('active');
                }
            });

            // 显示对应内容
            document.getElementById('generateTab').style.display = tabName === 'generate' ? 'block' : 'none';
            document.getElementById('listTab').style.display = tabName === 'list' ? 'block' : 'none';

            if (tabName === 'list') {
                console.log('切换到用例列表，开始加载数据...');
                loadTestCases();
            }
        }

        // 文件上传处理
        fileUpload.addEventListener('click', () => requirementFile.click());
        
        fileUpload.addEventListener('dragover', (e) => {
            e.preventDefault();
            fileUpload.classList.add('dragover');
        });
        
        fileUpload.addEventListener('dragleave', () => {
            fileUpload.classList.remove('dragover');
        });
        
        fileUpload.addEventListener('drop', (e) => {
            e.preventDefault();
            fileUpload.classList.remove('dragover');
            const files = e.dataTransfer.files;
            if (files.length > 0) {
                handleFileSelect(files[0]);
            }
        });
        
        requirementFile.addEventListener('change', (e) => {
            if (e.target.files.length > 0) {
                handleFileSelect(e.target.files[0]);
            }
        });

        function handleFileSelect(file) {
            const allowedTypes = ['.txt', '.doc', '.docx', '.pdf'];
            const fileExt = file.name.toLowerCase().substring(file.name.lastIndexOf('.'));

            if (!allowedTypes.includes(fileExt)) {
                showAlert('不支持的文件类型，请选择 .txt, .doc, .docx, .pdf 格式的文件', 'error');
                return;
            }

            // 显示文件基本信息
            const fileSize = formatFileSize(file.size);
            fileName.textContent = `${file.name} (${fileSize})`;

            // 显示文件路径信息
            let pathInfo = '浏览器安全限制，无法显示完整路径';
            if (file.webkitRelativePath) {
                pathInfo = `相对路径: ${file.webkitRelativePath}`;
            } else if (file.path) {
                pathInfo = `路径: ${file.path}`;
            }
            filePath.textContent = pathInfo;

            // 显示状态
            fileStatus.textContent = '正在解析文档...';
            fileStatus.style.color = '#ff9800';

            // 显示文件信息区域
            uploadedFile.classList.add('show');

            console.log('文件选择成功:', {
                name: file.name,
                size: file.size,
                type: file.type,
                lastModified: new Date(file.lastModified),
                path: file.path || '浏览器安全限制，无法获取完整路径'
            });

            // 解析文件内容
            parseDocument(file);
        }

        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }

        function removeFile() {
            requirementFile.value = '';
            uploadedFile.classList.remove('show');
            fileName.textContent = '';
            filePath.textContent = '';
            fileStatus.textContent = '';

            // 询问是否清空需求描述
            let currentContent = document.getElementById('requirement').value.trim();
            if (currentContent && currentContent.length > 0) {
                if (confirm('是否同时清空需求描述框中的内容？')) {
                    document.getElementById('requirement').value = '';
                }
            }
        }

        async function parseDocument(file) {
            let formData = new FormData();
            formData.append('file', file);

            try {
                // 更新状态显示
                fileStatus.textContent = '正在上传文档...';
                fileStatus.style.color = '#ff9800';
                showAlert('正在解析文档，请稍候...', 'info');

                let response = await fetch('/api/parse-document', {
                    method: 'POST',
                    body: formData
                });

                if (!response.ok) {
                    let errorData = await response.json();
                    throw new Error(errorData.detail || '解析文档失败');
                }

                let data = await response.json();

                if (data.requirement && data.requirement.trim()) {
                    // 清理解析的内容
                    const cleanedContent = cleanDocumentContent(data.requirement);

                    if (cleanedContent && cleanedContent.length > 10) {
                        // 获取当前需求描述框的内容
                        let currentContent = document.getElementById('requirement').value.trim();

                        // 如果当前有内容，询问是否替换
                        if (currentContent && currentContent.length > 0) {
                            if (confirm('需求描述框中已有内容，是否要替换为文档内容？\n\n点击"确定"替换，点击"取消"追加到末尾')) {
                                document.getElementById('requirement').value = cleanedContent;
                            } else {
                                document.getElementById('requirement').value = currentContent + '\n\n' + cleanedContent;
                            }
                        } else {
                            document.getElementById('requirement').value = cleanedContent;
                        }

                        // 更新状态为成功，显示更详细的信息
                        const sizeInfo = cleanedContent.length > 5000 ?
                            ` (大文件，${Math.round(cleanedContent.length/1000)}K字符)` :
                            ` (${cleanedContent.length}字符)`;
                        fileStatus.textContent = `解析成功 - 提取完整内容${sizeInfo}`;
                        fileStatus.style.color = '#4caf50';
                        showAlert(`文档解析成功！解析了 ${data.file_size} 字节的内容`, 'success');
                    } else {
                        fileStatus.textContent = '解析完成 - 未提取到有效内容';
                        fileStatus.style.color = '#ff9800';
                        showAlert('文档解析成功，但未提取到有效内容，请手动输入需求描述', 'warning');
                    }
                } else {
                    fileStatus.textContent = '解析完成 - 未提取到内容';
                    fileStatus.style.color = '#ff9800';
                    showAlert('文档解析成功，但未提取到内容，请手动输入需求描述', 'warning');
                }
            } catch (error) {
                console.error('解析文档失败:', error);
                fileStatus.textContent = `解析失败 - ${error.message}`;
                fileStatus.style.color = '#f44336';
                showAlert(`解析文档失败: ${error.message}`, 'error');
            }
        }

        function cleanDocumentContent(content) {
            if (!content) return '';

            // 移除常见的无用信息
            let cleaned = content
                // 移除URL和路径
                .replace(/https?:\/\/[^\s]+/g, '')
                .replace(/ftp:\/\/[^\s]+/g, '')
                .replace(/file:\/\/[^\s]+/g, '')
                .replace(/[A-Z]:\\[^\s]+/g, '')
                // 移除邮箱地址
                .replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '')
                // 移除多余的空白字符
                .replace(/\s+/g, ' ')
                // 移除多余的换行
                .replace(/\n\s*\n\s*\n/g, '\n\n')
                .trim();

            // 如果内容太短，返回空
            if (cleaned.length < 10) {
                return '';
            }

            // 优化：不再限制内容长度，保留完整内容
            // 对于大文件，提供完整内容以便AI更好地理解需求
            console.log(`文档内容长度: ${cleaned.length} 字符`);

            // 如果内容超过5000字符，给用户提示但仍保留完整内容
            if (cleaned.length > 5000) {
                console.log('检测到大文件，内容较长，建议检查是否包含不必要的信息');
            }

            return cleaned;
        }

        // 表单提交处理
        form.addEventListener('submit', async (e) => {
            e.preventDefault();
            
            let formData = new FormData(form);
            const requirement = formData.get('requirement').trim();
            
            if (!requirement) {
                showAlert('请输入需求描述或上传需求文档', 'error');
                return;
            }
            
            // 获取选中的测试类型
            const testTypes = [];
            document.querySelectorAll('.test-type-item input[type="checkbox"]:checked').forEach(checkbox => {
                testTypes.push(checkbox.value);
            });
            
            if (testTypes.length === 0) {
                testTypes.push('功能');
            }
            
            // 显示加载状态
            loading.classList.add('show');
            generateBtn.disabled = true;
            hideAlert();
            
            try {
                // 智能计算超时时间
                const smartTimeout = calculateSmartTimeout(requirement);
                console.log(`使用智能超时: ${smartTimeout/1000}秒`);

                // 创建AbortController来控制超时
                let controller = new AbortController();
                let timeoutId = setTimeout(() => controller.abort(), smartTimeout);

                let response = await fetch('/api/generate', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        requirement: requirement,
                        project_name: formData.get('projectName') || '',
                        module_name: formData.get('moduleName') || '',
                        test_types: testTypes,
                        test_executors: ['qa'],
                        test_design_methods: ['use_case']
                    }),
                    signal: controller.signal
                });

                clearTimeout(timeoutId);

                if (!response.ok) {
                    let errorData = await response.json();
                    throw new Error(errorData.detail || '生成失败');
                }

                let data = await response.json();

                // 保存到localStorage
                localStorage.setItem('testCases', JSON.stringify(data));

                showAlert(`测试用例生成成功！共生成 ${data.test_cases.length} 个用例`, 'success');

                // 自动切换到用例列表页面
                setTimeout(() => {
                    showTab('list');
                }, 1500);

            } catch (error) {
                if (error.name === 'AbortError') {
                    showAlert('请求超时，系统已自动重试和续点，请检查网络连接或稍后重试', 'error');
                } else {
                    showAlert('生成失败：' + error.message, 'error');
                }
            } finally {
                loading.classList.remove('show');
                generateBtn.disabled = false;
                // 隐藏详细进度信息
                document.getElementById('loadingDetails').style.display = 'none';
            }
        });

        // 更新进度信息
        function updateProgress(message, percentage = null) {
            const progressText = document.getElementById('progressText');
            if (progressText) {
                progressText.textContent = message;
            }

            // 显示详细进度信息
            const loadingDetails = document.getElementById('loadingDetails');
            if (loadingDetails) {
                loadingDetails.style.display = 'block';
            }
        }

        // 更新分批生成进度
        function updateBatchProgress(current, total, details = '') {
            const batchProgress = document.getElementById('batchProgress');
            const batchCurrent = document.getElementById('batchCurrent');
            const batchTotal = document.getElementById('batchTotal');
            const batchProgressFill = document.getElementById('batchProgressFill');
            const batchDetails = document.getElementById('batchDetails');

            if (total > 1) {
                // 显示分批进度
                batchProgress.style.display = 'block';
                batchCurrent.textContent = current;
                batchTotal.textContent = total;

                const percentage = (current / total) * 100;
                batchProgressFill.style.width = percentage + '%';

                if (details) {
                    batchDetails.textContent = details;
                }
            } else {
                // 隐藏分批进度
                batchProgress.style.display = 'none';
            }
        }

        // 智能计算超时时间 - 与后端保持一致
        function calculateSmartTimeout(requirement) {
            const requirementLength = requirement.length;
            let baseTimeout = 300000; // 5分钟基础时间（毫秒）

            // 根据需求长度调整基础超时时间（与后端逻辑一致）
            if (requirementLength > 3000) {
                baseTimeout = 900000; // 15分钟 - 超大需求
                updateProgress('检测到超大型需求，预计生成时间15-20分钟...');
            } else if (requirementLength > 2000) {
                baseTimeout = 720000; // 12分钟 - 大需求
                updateProgress('检测到大型需求，预计生成时间12-15分钟...');
            } else if (requirementLength > 1000) {
                baseTimeout = 600000; // 10分钟 - 中等需求
                updateProgress('检测到中等规模需求，预计生成时间8-12分钟...');
            } else if (requirementLength > 500) {
                baseTimeout = 480000; // 8分钟 - 小需求
                updateProgress('正在分析需求并生成测试用例，预计6-8分钟...');
            } else {
                baseTimeout = 360000; // 6分钟 - 最小需求
                updateProgress('正在快速生成测试用例，预计3-6分钟...');
            }

            // 检测分批生成场景，增加额外时间（与后端逻辑一致）
            const batchIndicators = [
                requirementLength > 1500,
                requirement.split('\n').length > 30,
                requirement.split('功能').length > 4,
                requirement.split('模块').length > 3,
                ['权限管理', '用户管理', '订单管理', '支付', '审计', '报表', '统计'].some(keyword => requirement.includes(keyword)),
                requirement.split('需求').length > 8,
                requirement.split('测试').length > 5
            ];

            const batchScore = batchIndicators.filter(Boolean).length;
            if (batchScore >= 2) {
                baseTimeout *= 1.5; // 分批生成需要更多时间
                updateProgress(`检测到复杂需求（复杂度评分: ${batchScore}/7），将采用分批生成策略...`);

                // 估算模块数量和总耗时
                const estimatedModules = Math.max(2, Math.min(6, Math.floor(requirementLength / 500)));
                const estimatedMinutes = Math.round(baseTimeout / 60000);
                updateProgress(`预计分解为${estimatedModules}个模块，总耗时可能达到${estimatedMinutes}分钟...`);
            }

            // 设置最大超时限制（30分钟）
            const maxTimeout = 1800000; // 30分钟
            const finalTimeout = Math.min(baseTimeout, maxTimeout);

            console.log(`智能超时计算: 需求长度=${requirementLength}, 基础超时=${baseTimeout/1000}s, 最终超时=${finalTimeout/1000}s, 复杂度评分=${batchScore}`);

            return finalTimeout;
        }

        // 加载测试用例列表 - 使用分页
        async function loadTestCases() {
            console.log('开始加载测试用例列表...');
            try {
                // 使用分页API
                let response = await fetch(`/api/test-cases?page=${currentPage}&page_size=${pageSize}`);
                console.log('API响应状态:', response.status);

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                let data = await response.json();
                console.log('API返回数据:', data);

                allTestCases = data.test_cases || [];
                totalTestCases = data.total || 0;

                console.log(`加载到 ${allTestCases.length} 个测试用例，总计 ${totalTestCases} 个`);
                displayTestCasesTable();
            } catch (error) {
                console.error('从API加载用例列表失败:', error);

                // 尝试从localStorage加载
                let savedCases = localStorage.getItem('testCases');
                console.log('尝试从localStorage加载:', savedCases ? '有数据' : '无数据');

                if (savedCases) {
                    let savedData = JSON.parse(savedCases);
                    if (savedData.test_cases && savedData.test_cases.length > 0) {
                        // 对localStorage数据进行分页处理
                        const allSavedCases = savedData.test_cases;
                        totalTestCases = allSavedCases.length;
                        const startIndex = (currentPage - 1) * pageSize;
                        const endIndex = startIndex + pageSize;
                        allTestCases = allSavedCases.slice(startIndex, endIndex);

                        console.log(`从localStorage加载到 ${allTestCases.length} 个测试用例，总计 ${totalTestCases} 个`);
                        displayTestCasesTable();
                    } else {
                        console.log('localStorage中没有有效的测试用例数据');
                        displayEmptyTable();
                    }
                } else {
                    console.log('localStorage中没有测试用例数据');
                    displayEmptyTable();
                }
            }
        }

        // 显示空表格
        function displayEmptyTable() {
            let tbody = document.getElementById('casesTableBody');
            tbody.innerHTML = `
                <tr>
                    <td colspan="6" style="text-align: center; padding: 40px; color: #666;">
                        暂无测试用例，请先生成用例
                    </td>
                </tr>
            `;
            // 显示空状态信息
            document.getElementById('pagination').innerHTML = `
                <div style="text-align: center; padding: 20px; color: #666; font-size: 14px;">
                    暂无测试用例
                </div>
            `;
        }

        // 显示测试用例表格 - 支持分页
        function displayTestCasesTable() {
            let tbody = document.getElementById('casesTableBody');
            if (allTestCases.length === 0) {
                displayEmptyTable();
                return;
            }

            // 显示当前页的用例
            tbody.innerHTML = allTestCases.map((testCase, index) => {
                // 优先使用case_id作为主键，这是数据库的主键
                const caseId = testCase.case_id || testCase.id || `TC${String(index + 1).padStart(3, '0')}`;
                const testCaseId = testCase.test_case_id || `test_${String(index + 1).padStart(3, '0')}`;
                const isSelected = selectedCases.has(caseId);

                // 安全地转义字符串，避免引号问题
                const safeCaseId = String(caseId).replace(/'/g, "\\'");
                const safeTitle = (testCase.title || `测试用例 ${index + 1}`).replace(/'/g, "\\'").replace(/"/g, '&quot;');

                return `
                    <tr>
                        <td>
                            <input type="checkbox" class="case-checkbox"
                                   value="${safeCaseId}"
                                   ${isSelected ? 'checked' : ''}
                                   onchange="toggleCaseSelection('${safeCaseId}')">
                        </td>
                        <td>
                            <span class="test-case-id">${testCaseId}</span>
                        </td>
                        <td>
                            <span class="case-priority priority-${testCase.priority?.toLowerCase() || 'p3'}">
                                ${testCase.priority || 'P3'}
                            </span>
                        </td>
                        <td>
                            <div class="case-title" title="${safeTitle}">
                                ${safeTitle.replace(/\s+/g, '-')}
                            </div>
                        </td>
                        <td>
                            <span class="case-category">${getTestTypeName(testCase.test_type)}</span>
                        </td>
                        <td>
                            <div class="case-actions">
                                <button class="btn-small btn-view" onclick="viewCaseDetail('${safeCaseId}')" type="button">查看</button>
                                <button class="btn-small btn-delete" onclick="deleteTestCase('${safeCaseId}')" type="button">删除</button>
                            </div>
                        </td>
                    </tr>
                `;
            }).join('');

            // 更新分页控件
            updatePagination();
            updateSelectAllCheckbox();
        }

        // 更新分页控件
        function updatePagination() {
            const pagination = document.getElementById('pagination');

            if (totalTestCases === 0) {
                pagination.innerHTML = `
                    <div style="text-align: center; padding: 20px; color: #666; font-size: 14px;">
                        暂无测试用例
                    </div>
                `;
                return;
            }

            const totalPages = Math.ceil(totalTestCases / pageSize);
            let paginationHTML = '';

            // 上一页按钮
            paginationHTML += `
                <button onclick="changePage(${currentPage - 1})" ${currentPage === 1 ? 'disabled' : ''}>
                    上一页
                </button>
            `;

            // 页码按钮
            const startPage = Math.max(1, currentPage - 2);
            const endPage = Math.min(totalPages, currentPage + 2);

            if (startPage > 1) {
                paginationHTML += `<button onclick="changePage(1)">1</button>`;
                if (startPage > 2) {
                    paginationHTML += `<span>...</span>`;
                }
            }

            for (let i = startPage; i <= endPage; i++) {
                paginationHTML += `
                    <button onclick="changePage(${i})" ${i === currentPage ? 'class="active"' : ''}>
                        ${i}
                    </button>
                `;
            }

            if (endPage < totalPages) {
                if (endPage < totalPages - 1) {
                    paginationHTML += `<span>...</span>`;
                }
                paginationHTML += `<button onclick="changePage(${totalPages})">${totalPages}</button>`;
            }

            // 下一页按钮
            paginationHTML += `
                <button onclick="changePage(${currentPage + 1})" ${currentPage === totalPages ? 'disabled' : ''}>
                    下一页
                </button>
            `;

            // 显示总数信息
            paginationHTML += `
                <span class="pagination-info">
                    第 ${currentPage} 页，共 ${totalPages} 页，总计 ${totalTestCases} 条
                </span>
            `;

            pagination.innerHTML = paginationHTML;
        }

        // 切换页面
        function changePage(page) {
            const totalPages = Math.ceil(totalTestCases / pageSize);
            if (page < 1 || page > totalPages) return;

            currentPage = page;
            loadTestCases(); // 重新加载数据
        }

        // 改变每页数量
        function changePageSize(newPageSize) {
            pageSize = parseInt(newPageSize);
            currentPage = 1; // 重置到第一页
            loadTestCases(); // 重新加载数据
        }

        // 切换用例选择状态
        function toggleCaseSelection(caseId) {
            if (selectedCases.has(caseId)) {
                selectedCases.delete(caseId);
            } else {
                selectedCases.add(caseId);
            }
            updateSelectAllCheckbox();
        }

        // 全选/取消全选
        function toggleSelectAll() {
            let selectAllCheckbox = document.getElementById('selectAll');
            let checkboxes = document.querySelectorAll('.case-checkbox');
            
            if (selectAllCheckbox.checked) {
                checkboxes.forEach(checkbox => {
                    checkbox.checked = true;
                    selectedCases.add(checkbox.value);
                });
            } else {
                checkboxes.forEach(checkbox => {
                    checkbox.checked = false;
                    selectedCases.delete(checkbox.value);
                });
            }
        }

        // 全选
        function selectAllCases() {
            let checkboxes = document.querySelectorAll('.case-checkbox');
            checkboxes.forEach(checkbox => {
                checkbox.checked = true;
                selectedCases.add(checkbox.value);
            });
            document.getElementById('selectAll').checked = true;
        }

        // 取消全选
        function deselectAllCases() {
            let checkboxes = document.querySelectorAll('.case-checkbox');
            checkboxes.forEach(checkbox => {
                checkbox.checked = false;
                selectedCases.delete(checkbox.value);
            });
            document.getElementById('selectAll').checked = false;
        }

        // 更新全选复选框状态
        function updateSelectAllCheckbox() {
            let checkboxes = document.querySelectorAll('.case-checkbox');
            let selectAllCheckbox = document.getElementById('selectAll');
            const checkedCount = document.querySelectorAll('.case-checkbox:checked').length;
            
            if (checkboxes.length === 0) {
                selectAllCheckbox.checked = false;
                selectAllCheckbox.indeterminate = false;
                return;
            }
            
            selectAllCheckbox.checked = checkedCount === checkboxes.length;
            selectAllCheckbox.indeterminate = checkedCount > 0 && checkedCount < checkboxes.length;
        }

        // 查看用例详情
        async function viewCaseDetail(caseId) {
            console.log('=== 查看用例详情 ===');
            console.log('传入的caseId:', caseId, '类型:', typeof caseId);

            try {
                // 先在当前页面数据中查找
                let testCase = allTestCases.find(testCase => {
                    const match1 = testCase.case_id === caseId;
                    const match2 = testCase.id === caseId;
                    const match3 = testCase.test_case_id === caseId;
                    const match4 = String(testCase.case_id) === String(caseId);
                    const match5 = String(testCase.id) === String(caseId);
                    return match1 || match2 || match3 || match4 || match5;
                });

                // 如果当前页面没有找到，从API获取
                if (!testCase) {
                    console.log('当前页面未找到用例，从API获取...');
                    const response = await fetch(`/api/test-cases/${caseId}`);
                    if (!response.ok) {
                        throw new Error('获取用例详情失败');
                    }
                    testCase = await response.json();
                }

                if (!testCase) {
                    showAlert(`用例不存在 (ID: ${caseId})`, 'error');
                    return;
                }

                console.log('找到用例:', testCase);

                const modal = document.getElementById('caseDetailModal');
                const content = document.getElementById('caseDetailContent');

                const stepsHtml = testCase.steps ? testCase.steps.map((step, index) => `
                    <div class="step-item">
                        <div class="step-number">步骤 ${step.step_number || index + 1}</div>
                        <div class="step-description">${step.description || '步骤描述'}</div>
                        <div class="step-expected">预期结果: ${step.expected_result || '操作成功'}</div>
                    </div>
                `).join('') : '';

                content.innerHTML = `
                    <div class="detail-item">
                        <div class="detail-label">数据库ID</div>
                        <div class="detail-value">${testCase.case_id || caseId}</div>
                    </div>
                    <div class="detail-item">
                        <div class="detail-label">用例ID</div>
                        <div class="detail-value">${testCase.test_case_id || 'TEST_001'}</div>
                    </div>
                    <div class="detail-item">
                        <div class="detail-label">用例标题</div>
                        <div class="detail-value">${testCase.title || '测试用例'}</div>
                    </div>
                    <div class="detail-item">
                        <div class="detail-label">优先级</div>
                        <div class="detail-value">${testCase.priority || 'P3'}</div>
                    </div>
                    <div class="detail-item">
                        <div class="detail-label">测试类型</div>
                        <div class="detail-value">${getTestTypeName(testCase.test_type)}</div>
                    </div>
                    <div class="detail-item">
                        <div class="detail-label">前置条件</div>
                        <div class="detail-value">${testCase.preconditions || '系统正常运行'}</div>
                    </div>
                    <div class="detail-item">
                        <div class="detail-label">测试步骤</div>
                        <div class="steps-list">
                            ${stepsHtml || '<div class="detail-value">暂无测试步骤</div>'}
                        </div>
                    </div>
                    ${testCase.created_time ? `
                    <div class="detail-item">
                        <div class="detail-label">创建时间</div>
                        <div class="detail-value">${new Date(testCase.created_time).toLocaleString()}</div>
                    </div>
                    ` : ''}
                `;

                modal.style.display = 'block';
            } catch (error) {
                console.error('查看用例详情失败:', error);
                showAlert('查看用例详情失败：' + error.message, 'error');
            }
        }

        // 关闭用例详情
        function closeCaseDetail() {
            document.getElementById('caseDetailModal').style.display = 'none';
        }

        // 导出选中的用例
        async function exportSelectedCases() {
            console.log('导出选中用例，selectedCases:', selectedCases);

            if (selectedCases.size === 0) {
                showAlert('请先选择要导出的用例', 'error');
                return;
            }

            try {
                // 获取选中用例的完整数据
                const selectedCaseIds = Array.from(selectedCases);
                console.log('选中的用例ID:', selectedCaseIds);

                // 创建AbortController来控制超时
                let controller = new AbortController();
                let timeoutId = setTimeout(() => controller.abort(), 300000); // 5分钟超时

                let response = await fetch('/api/export-excel', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        case_ids: selectedCaseIds // 发送用例ID，让后端查询完整数据
                    }),
                    signal: controller.signal
                });

                clearTimeout(timeoutId);

                if (!response.ok) {
                    let errorData = await response.json().catch(() => ({}));
                    throw new Error(errorData.detail || `导出失败: ${response.status} ${response.statusText}`);
                }

                let blob = await response.blob();
                let url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `测试用例_${new Date().toISOString().slice(0, 10)}.xlsx`;
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                a.remove();

                showAlert('导出成功！', 'success');
            } catch (error) {
                console.error('导出失败:', error);
                if (error.name === 'AbortError') {
                    showAlert('导出超时，请稍后重试', 'error');
                } else {
                    showAlert('导出失败：' + error.message, 'error');
                }
            }
        }



        // 删除选中的用例
        async function deleteSelectedCases() {
            if (selectedCases.size === 0) {
                showAlert('请先选择要删除的用例', 'error');
                return;
            }
            
            if (!confirm(`确定要删除选中的 ${selectedCases.size} 个测试用例吗？`)) {
                return;
            }
            
            try {
                const deletePromises = Array.from(selectedCases).map(caseId =>
                    fetch(`/api/test-cases/${caseId}`, { method: 'DELETE' })
                );
                
                await Promise.all(deletePromises);
                
                selectedCases.clear();
                showAlert('选中的测试用例删除成功', 'success');
                loadTestCases(); // 重新加载列表
            } catch (error) {
                showAlert('删除失败：' + error.message, 'error');
            }
        }

        // 删除单个测试用例
        async function deleteTestCase(caseId) {
            console.log('删除用例，caseId:', caseId);

            if (!confirm('确定要删除这个测试用例吗？')) {
                return;
            }
            
            try {
                let response = await fetch(`/api/test-cases/${caseId}`, {
                    method: 'DELETE'
                });
                
                if (!response.ok) {
                    throw new Error('删除失败');
                }
                
                showAlert('测试用例删除成功', 'success');
                loadTestCases(); // 重新加载列表
            } catch (error) {
                showAlert('删除失败：' + error.message, 'error');
            }
        }



        // 导出所有测试用例
        async function exportTestCases() {
            try {
                console.log('准备导出所有用例...');

                // 创建AbortController来控制超时
                let controller = new AbortController();
                let timeoutId = setTimeout(() => controller.abort(), 300000); // 5分钟超时

                // 导出所有用例，不传递case_ids参数
                let response = await fetch('/api/export-excel', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({}), // 空对象表示导出所有用例
                    signal: controller.signal
                });

                clearTimeout(timeoutId);

                if (!response.ok) {
                    let errorData = await response.json().catch(() => ({}));
                    throw new Error(errorData.detail || `导出失败: ${response.status} ${response.statusText}`);
                }

                let blob = await response.blob();
                let url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.href = url;
                a.download = `测试用例_${new Date().toISOString().slice(0, 10)}.xlsx`;
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url);
                a.remove();

                showAlert('导出成功！', 'success');
            } catch (error) {
                console.error('导出失败:', error);
                if (error.name === 'AbortError') {
                    showAlert('导出超时，请稍后重试', 'error');
                } else {
                    showAlert('导出失败：' + error.message, 'error');
                }
            }
        }

        function showAlert(message, type) {
            alert.textContent = message;
            alert.className = `alert ${type} show`;
        }

        function hideAlert() {
            alert.classList.remove('show');
        }

        // 添加新的测试类型切换逻辑
        function toggleTestType(element) {
            const checkbox = element.querySelector('input[type="checkbox"]');
            
            // 切换选中状态
            checkbox.checked = !checkbox.checked;
            
            // 添加选中动画效果
            if (checkbox.checked) {
                element.classList.add('selected');
                // 移除选中动画类
                setTimeout(() => {
                    element.classList.remove('selected');
                }, 300);
            }
            
            // 阻止事件冒泡
            event.stopPropagation();
        }

        // 页面加载时初始化测试类型样式和加载测试用例
        document.addEventListener('DOMContentLoaded', function() {
            // 为已选中的测试类型添加选中样式
            document.querySelectorAll('.test-type-item input[type="checkbox"]:checked').forEach(checkbox => {
                const item = checkbox.closest('.test-type-item');
                if (item) {
                    item.classList.add('selected');
                }
            });

            // 页面加载时自动加载测试用例数据
            console.log('页面加载完成，开始加载测试用例数据...');
            loadTestCases();
        });
    </script>
</body>
</html> 